/*
 * Date 	: 2015.03.10 19:23:46
 * Author	: Newpub
 */
package com.gdface.admin.gdface_attend;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.RatingBar;
import android.widget.TextView;
import android.widget.Toast;

import com.gdface.admin.gdface_attend.utils.DaoUtils;
import com.gdface.admin.gdface_attend.utils.DateUtils;
import com.iotimc.comass.bean.IoOutCommon;
import com.iotimc.comass.util.IotimcSerialHelper;
import com.pefis.natives.Ast2600JNI;
import com.pefis.natives.PfsBioInfo;

import net.gdface.face.Entity.Att_log;
import net.gdface.face.Entity.Att_user;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;

public class IdentifyActivity extends Activity implements Runnable {

    ImageView mIdentifyFaceView;
    FaceDetectionView mFaceDetectionView;
    TextView mUserIDTxt;
    RatingBar mRatingBar;
    ImageView mPhoto;
    CheckBox mSwitchCamera;
    TextView mCandInfoText;
    private Button startEnroll;
    private boolean mColorCamera;
    private int mImageWidth;
    private int mImageHeight;
    private Thread mface_pro;
    public boolean m_bExitLoop = false;
    private byte[] mColorImageFrame;
    private byte[] mProcessImageFrame;
    public byte[] m_UpdateTemplate;
    private byte[] mPhotoImage;
    private long[] mCandInfo;
    private int mContextID;
    private int sum_hint_fail = 0;

    private boolean isToAdmin = false;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_identify);
        IotimcSerialHelper.getCmdInitFile(this);
        initCommon();

        DateFormat df = new SimpleDateFormat("yyyy_MM_dd");
        Calendar calendar = Calendar.getInstance();
        PHOTO_CAMERA_PATH = PfsBioInfo.INIT_DATA_PATH + "/" + df.format(calendar.getTime()) + "/";

        mIdentifyFaceView = (ImageView) this.findViewById(R.id.EnrollFaceView);
        mFaceDetectionView = (FaceDetectionView) this.findViewById(R.id.FaceDetectionView);
        mUserIDTxt = (TextView) this.findViewById(R.id.identified_id);
        mPhoto = (ImageView) this.findViewById(R.id.photo);
        mSwitchCamera = (CheckBox) this.findViewById(R.id.switch_camera);
        mSwitchCamera.setVisibility(View.INVISIBLE);
        mCandInfoText = (TextView) this.findViewById(R.id.cand_info);
        startEnroll = (Button) findViewById(R.id.enroll_start);

        startEnroll.setOnClickListener(listener);

        mImageWidth = PfsBioInfo.getInstance().face_img_w[0];
        mImageHeight = PfsBioInfo.getInstance().face_img_h[0];
        mColorImageFrame = new byte[mImageWidth * mImageHeight];
        mProcessImageFrame = new byte[mImageWidth * mImageHeight];
        mPhotoImage = new byte[mImageWidth * mImageHeight * 4];
        mCandInfo = new long[PfsBioInfo.PFSBIO_CAND_STRUCT];

        m_UpdateTemplate = new byte[PfsBioInfo.getInstance().enroll_template_size[0]];
        mface_pro = new Thread(this);
        m_bExitLoop = true;
        mface_pro.start();
        mSwitchCamera.setOnCheckedChangeListener(mCheckedChangeListener);
        mColorCamera = true;
        mContextID = PfsBioInfo.getInstance().mContextID;

        List<Att_user> list = DaoUtils.findUser();
        List<Att_log> list_log = DaoUtils.findLog();
        Log.i("hwwlog", "list.size = " + list.size());
        for (int i = 0; i < list.size(); i++) {
            Log.i("hwwlog", "id = " + list.get(i).toString());
        }
//        for (int i = 0; i < list_log.size(); i++) {
//            Log.i("hwwlog", "id = " + list_log.get(i).toString());
//        }
    }

    View.OnClickListener listener = new View.OnClickListener() {
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }

        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.enroll_start:
//                    new AlertDialog.Builder(IdentifyActivity.this).setTitle("").setMessage("").setNegativeButton("")
                    showPOP();
                    break;
                case R.id.pop_admin_face:
                    isToAdmin = true;
                    pop.dismiss();
                    break;
                case R.id.pop_admin_pass:
//                    new AlertDialog.Builder()
                    startToAdmin();
                    pop.dismiss();
                    break;
            }
        }
    };

    private PopupWindow pop;

    private void showPOP() {
        View contentView = LayoutInflater.from(IdentifyActivity.this).inflate(R.layout.pop_admin, null);
        pop = new PopupWindow(contentView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);

        TextView tv_face = (TextView) contentView.findViewById(R.id.pop_admin_face);
        TextView tv_pass = (TextView) contentView.findViewById(R.id.pop_admin_pass);
        tv_face.setOnClickListener(listener);
        tv_pass.setOnClickListener(listener);

        View rootView = LayoutInflater.from(IdentifyActivity.this).inflate(R.layout.activity_identify, null);
        pop.setBackgroundDrawable(new ColorDrawable(0x00000000));
        pop.setOutsideTouchable(true);
        pop.setFocusable(true);
//        pop.showAtLocation(rootView, Gravity.BOTTOM,0,0);
        pop.showAsDropDown(startEnroll);
    }

    private void startToAdmin() {
        try {
            m_bExitLoop = false;
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        startActivity(new Intent(IdentifyActivity.this, AdminActivity.class));
        IdentifyActivity.this.finish();
    }

    private OnCheckedChangeListener mCheckedChangeListener = new OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

            mColorCamera = !mColorCamera;
        }
    };

    Handler mImageDraw = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            mIdentifyFaceView.setImageBitmap((Bitmap) msg.obj);
        }
    };

    @Override
    public void onBackPressed() {
        finish();
        m_bExitLoop = false;
        PfsBioInfo.getInstance().killMediaPlayer();

    }


    @Override
    public void onDestroy() {
        // Don't forget to shutdown!
        IotimcSerialHelper.quit();
        PfsBioInfo.getInstance().killMediaPlayer();
        m_bExitLoop = false;

        super.onDestroy();
    }

    public void DrawFaceImage(byte[] rawData, Boolean IsSave) {

        if (mColorCamera)
            PfsBioInfo.getInstance().CreateColorBitmapFromBayer(rawData);
        else
            PfsBioInfo.getInstance().CreateGrayBitmapFromBayer(rawData);

        mImageDraw.obtainMessage(0, PfsBioInfo.getInstance().m_bmp).sendToTarget();
    }


    @Override
    public void run() {
        // TODO Auto-generated method stub
        int vnRet;
        int[] update_tmpl_flag = new int[1];
        int[] identified_id = new int[1];
        Ast2600JNI.getInstance().pisFcInfraredLedControl(mContextID, PfsBioInfo.PFSBIO_IR_LED_HIGH_ON);
        short[] faceRect = new short[8];
        while (m_bExitLoop) {
            if (mColorCamera) {
                Ast2600JNI.getInstance().pisFcColorImageCapture(PfsBioInfo.getInstance().mContextID, mColorImageFrame);
                Ast2600JNI.getInstance().pisFcGrayImageCapture(PfsBioInfo.getInstance().mContextID, mProcessImageFrame);
                DrawFaceImage(mColorImageFrame, true);
            } else {
                Ast2600JNI.getInstance().pisFcGrayImageCapture(PfsBioInfo.getInstance().mContextID, mProcessImageFrame);
                DrawFaceImage(mProcessImageFrame, true);
            }
            vnRet = Ast2600JNI.getInstance().pisFcCheck(mContextID, mProcessImageFrame, mImageWidth, mImageHeight, faceRect);
            if (vnRet != PfsBioInfo.PFSBIO_OK) {

                Ast2600JNI.getInstance().pisLedControl(mContextID, PfsBioInfo.PFSBIO_OKNOLED, PfsBioInfo.PFSBIO_LED_OFF);

                mShowResult.sendEmptyMessage(0);
                mFaceDetectionView.setRect(-10, -10, -10, -10);
                mFaceDetectionView.postInvalidate();
                continue;
            }
            mFaceDetectionView.setRect(faceRect[0], faceRect[2], faceRect[1] - faceRect[0], faceRect[3] - faceRect[2]);
            mFaceDetectionView.postInvalidate();
            vnRet = Ast2600JNI.getInstance().pisFcIdentify(mContextID, mProcessImageFrame, mImageWidth, mImageHeight, identified_id, mCandInfo, m_UpdateTemplate, update_tmpl_flag);

            if (vnRet == PfsBioInfo.PFSBIO_OK) {
                Ast2600JNI.getInstance().pisLedControl(mContextID, PfsBioInfo.PFSBIO_OKLED, PfsBioInfo.PFSBIO_LED_ON);
                mShowResult.sendEmptyMessage(identified_id[0]);
//                Log.i("hwwlog","id success = "+identified_id[0]);
//                Att_user user = DaoUtils.findUser(Long.valueOf(identified_id[0]));
//
//                if (PfsBioInfo.isSaveImg) {
//                    int i;
//                    for (int j = 0; j < PfsBioInfo.getInstance().face_img_h[0]; j++)
//                        for (int k = 0; k < PfsBioInfo.getInstance().face_img_w[0]; k++) {
//                            i = j * PfsBioInfo.getInstance().face_img_w[0] + k;
//                            iden_byte[i * 4] = iden_byte[i * 4 + 1] = iden_byte[i * 4 + 2] = mProcessImageFrame[i]; //Invert the source bits
//                            iden_byte[i * 4 + 3] = -1; //0xff, that's the alpha.
//                        }
//                    iden_bmp.copyPixelsFromBuffer(ByteBuffer.wrap(iden_byte));
//                }
//
//                if (id_suc != identified_id[0]) {
//                    id_suc = identified_id[0];
//                    time_suc = System.currentTimeMillis();
//                    if (PfsBioInfo.isSaveImg) {
//                        ImgInfo info_color = new ImgInfo(PfsBioInfo.TYPE_COLOR, user.getUserNo(), PfsBioInfo.getInstance().m_bmp);
//                        ImgInfo info_gray = new ImgInfo(PfsBioInfo.TYPE_GRAY, user.getUserNo(), iden_bmp);
//                        new ImgTask().execute(info_color);
//                        new ImgTask().execute(info_gray);
//                    }
//
//                    if (null == user)
//                        return;
//                    log_insert(user);
//                } else {
//                    if (System.currentTimeMillis() - time_suc > 3000) {
//                        time_suc = System.currentTimeMillis();
//                        if (PfsBioInfo.isSaveImg) {
//                            ImgInfo info_color = new ImgInfo(PfsBioInfo.TYPE_COLOR, user.getUserNo(), PfsBioInfo.getInstance().m_bmp);
//                            ImgInfo info_gray = new ImgInfo(PfsBioInfo.TYPE_GRAY, user.getUserNo(), iden_bmp);
//                            new ImgTask().execute(info_color);
//                            new ImgTask().execute(info_gray);
//                        }
//
//                        if (null == user)
//                            return;
//                        log_insert(user);
//                    }
//                }
//                if (id_suc != identified_id[0]) {
//                    id_suc = identified_id[0];
//                    time_suc = System.currentTimeMillis();
//                    if (null == user)
//                        return;
//                    log_insert(user);
//                } else {
//                    if (System.currentTimeMillis() - time_suc > 3000) {
//                        time_suc = System.currentTimeMillis();
//
//                        if (null == user)
//                            return;
//                        log_insert(user);
//                    }
//                }

                try {
                    PfsBioInfo.getInstance().playAudio(PfsBioInfo.AUDIO_DING);
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                if (update_tmpl_flag[0] == 1) {
                    PfsBioInfo.getInstance().WriteByteToFile(m_UpdateTemplate, PfsBioInfo.TEMPLATE_DB_PATH + identified_id[0]);
                }
                sum_hint_fail = 0;
            } else {
                mShowResult.sendEmptyMessage(0);
                Ast2600JNI.getInstance().pisLedControl(mContextID, PfsBioInfo.PFSBIO_NOLED, PfsBioInfo.PFSBIO_LED_ON);

//                sum_hint_fail++;
//                if (15 < sum_hint_fail) {
//                    sum_hint_fail = 0;
//                    mHandler.sendEmptyMessage(0x80);
//
//                    if (PfsBioInfo.isSaveImg) {
//                        int i;
//                        for (int j = 0; j < PfsBioInfo.getInstance().face_img_h[0]; j++)
//                            for (int k = 0; k < PfsBioInfo.getInstance().face_img_w[0]; k++) {
//                                i = j * PfsBioInfo.getInstance().face_img_w[0] + k;
//                                iden_byte[i * 4] = iden_byte[i * 4 + 1] = iden_byte[i * 4 + 2] = mProcessImageFrame[i]; //Invert the source bits
//                                iden_byte[i * 4 + 3] = -1; //0xff, that's the alpha.
//                            }
//                        iden_bmp.copyPixelsFromBuffer(ByteBuffer.wrap(iden_byte));
//
//                        ImgInfo info_color = new ImgInfo(PfsBioInfo.TYPE_COLOR, "Unknow", PfsBioInfo.getInstance().m_bmp);
//                        ImgInfo info_gray = new ImgInfo(PfsBioInfo.TYPE_GRAY, "Unknow", iden_bmp);
//                        new ImgTask().execute(info_color);
//                        new ImgTask().execute(info_gray);
//                    }
//                }
            }
        }
        Ast2600JNI.getInstance().pisFcInfraredLedControl(mContextID, PfsBioInfo.PFSBIO_IR_LED_LOW_ON);
        Ast2600JNI.getInstance().pisLedControl(mContextID, PfsBioInfo.PFSBIO_OKNOLED, PfsBioInfo.PFSBIO_LED_OFF);
    }


    private int id_suc = 0, id_fai = 0;
    private long time_suc = 0, time_fai = 0;
    public byte[] iden_byte = new byte[PfsBioInfo.getInstance().face_img_h[0] * PfsBioInfo.getInstance().face_img_w[0] * 4];
    private Bitmap iden_bmp = Bitmap.createBitmap(PfsBioInfo.getInstance().face_img_w[0], PfsBioInfo.getInstance().face_img_h[0], Bitmap.Config.ARGB_8888);

    Handler mHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 0x80:
                    Toast.makeText(IdentifyActivity.this, "无法辨识，请找管理员!!", Toast.LENGTH_SHORT).show();
                    break;
                case 0x81:
                    mUserIDTxt.setText("");
                    mCandInfoText.setText("工号 : " + "");
                    break;
                case 0x99:
                    ioOutCommon.close();
                    break;
            }
        }
    };

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            mHandler.sendEmptyMessage(0x81);
        }
    };

    private long time_insert_log = 0;
    private long time_show_id = 0;
    private String save_id = "0";
    private int sum_admin_face = 0;

    Handler mShowResult = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            String msg_str;
            String vCandMessage;
            if (msg.what != 0) {
                Att_user user = DaoUtils.findUser(Long.valueOf(msg.what));
                if (null == user)
                    return;
                if (isToAdmin) {
                    if (1 == user.getPermission()) {
                        startToAdmin();
                    } else {
                        sum_admin_face++;
                        if (sum_admin_face > 9) {
                            isToAdmin = false;
                        }
                        Toast.makeText(IdentifyActivity.this, "你不是管理员，请确认!", Toast.LENGTH_SHORT).show();
                    }
                }
                msg_str = "" + msg.what;
                mUserIDTxt.setText(msg_str);
                mCandInfoText.setText("工号 : " + user.getUserNo());

                if (System.currentTimeMillis() - time_show_id > 2500) {
                    time_show_id = System.currentTimeMillis();
                    mHandler.postDelayed(runnable, 2500);
                } else {
                    if (!save_id.equals(msg_str)) {
                        mHandler.removeCallbacks(runnable);
                        mHandler.postDelayed(runnable, 2500);
                    }
                }
                save_id = msg_str;
                String picPath = PfsBioInfo.PHOTO_DB_PATH + msg.what + ".JPEG";
                if (fileIsExists(picPath)) {
//                    File file = new File(picPath);
//                    Glide.with(IdentifyActivity.this).load(file).into(mPhoto);
                    mPhoto.setImageURI(Uri.fromFile(new File(picPath)));
                }
                OpenDoorIO();
            } else {
                mPhoto.setImageBitmap(null);
                mPhoto.setBackgroundResource(R.drawable.noavatar_middle);
            }

//            vCandMessage = "";
//            for (int i = 0; i < mCandInfo[0]; i++) {
//                vCandMessage += "  " + mCandInfo[i + 1] + " (" + mCandInfo[i + 5] + ")\n";
//            }
//            mCandInfoText.setText(vCandMessage);
        }
    };

    boolean isUp = false;

    private void log_insert(Att_user user) {
        Att_log att_log = new Att_log();
//                Att_log.setId(null);
        String date_now = DateUtils.getNowDate();

//        AttendLogManager lm = new AttendLogManager();
//        AttendLogBean log_bean = lm.createAttendLogBean();
//        log_bean.setCompany(user.getCompany());
//        log_bean.setUserno(user.getUserNo());
//        log_bean.setAttendtime(date_now);
//        log_bean.setUpdatetime(date_now);
//        try {
//            MySQLUtils.insertLog(log_bean);
//            isUp = true;
//        } catch (DAOException e) {
//            isUp = false;
//            e.printStackTrace();
//        }

        att_log.setCompany(user.getCompany());
        att_log.setUserNo(user.getUserNo());
        att_log.setAttend_time(date_now);
        if (isUp) {
            att_log.setUpdata_time(date_now);
        } else {
            att_log.setUpdata_time(DaoUtils.updateTime_def);
        }
        DaoUtils.insertLog(att_log);
//        Log.i("hwwlog", "Att_log = " + att_log.toString());


    }


    //判断文件是否存在
    public boolean fileIsExists(String strFile) {
        try {
            File f = new File(strFile);
            if (!f.exists()) {
                return false;
            }

        } catch (Exception e) {
            return false;
        }

        return true;
    }


    private long time_door = 0;

    private void OpenDoorIO() {
        if (System.currentTimeMillis() - time_door > 3000) {
            time_door = System.currentTimeMillis();
            ioOutCommon.open();
            mHandler.sendEmptyMessageDelayed(0x99, 800);
        }
    }


    private Handler handler = new Handler();
    private IoOutCommon ioOutCommon;
    String info = "";

    private void initCommon() {
        ioOutCommon = new IoOutCommon(new IoOutCommon.OnListener() {
            @Override
            public void opened(short result, short addr, int type) {
                if (result == 0) {
                    info = "开IO成功";
                } else if (result == 1) {
                    info = "开IO失败";
                }

                handler.post(new Runnable() {
                    @Override
                    public void run() {
//                        Log.i("hwwlog", info);
                        info = "";
                    }
                });
            }

            @Override
            public void closed(short result, short addr, int type) {
                if (result == 0) {
                    info = "关IO成功";
                } else if (result == 1) {
                    info = "关IO失败";
                }
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        Log.i("hwwlog", info);
                        info = "";
                    }
                });
            }

            @Override
            public void getStatus(short result, short addr, short status) {
                if (result == 0) {
                    if (status == 1)
                        info = "关状态";
                    else if (status == 2)
                        info = "开状态";
                } else if (result == 1) {
                    info = "查状态失败";
                }
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        Log.i("hwwlog", info);
                        info = "";
                    }
                });

            }
        });
    }

    private String PHOTO_CAMERA_PATH;

    private void saveImageData(String type, String userNo, byte[] data) {

        String dir = PHOTO_CAMERA_PATH;
        File filename = new File(dir);
        if (!filename.exists()) {
            filename.mkdir();
        }

        String name = userNo + getAskTime() + ".JPEG";
        if (type.equals(PfsBioInfo.TYPE_COLOR)) {
            name = userNo + "_" + getAskTime() + "_" + "BGR.JPEG";
        } else if (type.equals(PfsBioInfo.TYPE_GRAY)) {
            name = userNo + "_" + getAskTime() + "_" + "INF.JPEG";
        }

        filename = new File(dir, name);

        if (filename.exists()) {
            filename.delete();
        }

        try {
            filename.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            FileOutputStream out = new FileOutputStream(filename);
            out.write(data);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        Log.i("hwwlog", "保存" + dir + "     " + name + "");
    }

    private String getAskTime() {
        DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
        Calendar calendar = Calendar.getInstance();
        String dateName = df.format(calendar.getTime());
        return dateName;
    }

    class ImgTask extends AsyncTask<ImgInfo, Void, Void> {
        @Override
        protected Void doInBackground(ImgInfo... params) {
            ImgInfo info = params[0];

            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            info.getBitmap().compress(Bitmap.CompressFormat.JPEG, 50, outputStream);

            saveImageData(info.getType(), info.getUserNo(), outputStream.toByteArray());
            return null;
        }

    }

    class ImgInfo {
        private String type, userNo;
        private Bitmap bitmap;

        public ImgInfo(String type, String userNo, Bitmap bitmap) {
            this.type = type;
            this.userNo = userNo;
            this.bitmap = bitmap;
        }

        public String getType() {
            return type;
        }

        public String getUserNo() {
            return userNo;
        }

        public Bitmap getBitmap() {
            return bitmap;
        }
    }

}
 